package com.hmkj.core.model.quote;

import com.xiaoleilu.hutool.util.StrUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;

/**
 * 实时行情数据
 *
 * @author Vector
 * @create 2017-11-14 14:57
 */
@Data
public class RealTimeData {
    /**
     * 交易类别
     */
    @ApiModelProperty(value = "交易类别")
    private String fet;
    /**
     * 合约代码
     */
    @ApiModelProperty(value = "合约代码")
    private String cc;
    /**
     * 品种代码类别
     */
    @ApiModelProperty(value = "品种代码类别")
    private String ct;
    /**
     * 产品类型
     */
    @ApiModelProperty(value = "产品类型")
    private String fpt;
    /**
     * 第二腿合约代码
     */
    @ApiModelProperty(value = "第二腿合约代码")
    private String sc;
    /**
     * 发送者机构编号
     */
    @ApiModelProperty(value = "发送者机构编号")
    private String si;
    /**
     * 目标机构编号
     */
    @ApiModelProperty(value = "目标机构编号")
    private String ci;
    /**
     * 开盘价
     */
    @ApiModelProperty(value = "开盘价")
    private BigDecimal op;
    /**
     * 最高价
     */
    @ApiModelProperty(value = "最高价")
    private BigDecimal hp;
    /**
     * 最低价
     */
    @ApiModelProperty(value = "最低价")
    private BigDecimal lp;
    /**
     * 最新价
     */
    @ApiModelProperty(value = "最新价")
    private BigDecimal np;
    /**
     * 昨日收盘价
     */
    @ApiModelProperty(value = "昨日收盘价")
    private BigDecimal pp;
    /**
     * 上限价
     */
    @ApiModelProperty(value = "上限价")
    private BigDecimal up;
    /**
     * 下限价
     */
    @ApiModelProperty(value = "下限价")
    private BigDecimal dp;
    /**
     * 成交金额
     */
    @ApiModelProperty(value = "成交金额")
    private BigDecimal bb;
    /**
     * 成交数量
     */
    @ApiModelProperty(value = "成交数量")
    private int ba;
    /**
     * 前结算价
     */
    @ApiModelProperty(value = "前结算价")
    private BigDecimal psp;
    /**
     * 持仓量
     */
    @ApiModelProperty(value = "持仓量")
    private int po;
    /**
     * 结算价
     */
    @ApiModelProperty(value = "结算价")
    private BigDecimal sp;
    /**
     * 平均价
     */
    @ApiModelProperty(value = "平均价")
    private BigDecimal avp;
    /**
     * 卖一价
     */
    @ApiModelProperty(value = "卖一价")
    private BigDecimal ap1;
    /**
     * 卖二价
     */
    @ApiModelProperty(value = "卖二价")
    private BigDecimal ap2;
    /**
     * 卖三价
     */
    @ApiModelProperty(value = "卖三价")
    private BigDecimal ap3;
    /**
     * 卖四价
     */
    @ApiModelProperty(value = "卖四价")
    private BigDecimal ap4;
    /**
     * 卖五价
     */
    @ApiModelProperty(value = "卖五价")
    private BigDecimal ap5;
    /**
     * 卖一量
     */
    @ApiModelProperty(value = "卖一量")
    private int av1;
    /**
     * 卖二量
     */
    @ApiModelProperty(value = "卖二量")
    private int av2;
    /**
     * 卖三量
     */
    @ApiModelProperty(value = "卖三量")
    private int av3;
    /**
     * 卖四量
     */
    @ApiModelProperty(value = "卖四量")
    private int av4;
    /**
     * 卖五量
     */
    @ApiModelProperty(value = "卖五量")
    private int av5;
    /**
     * 买一价
     */
    @ApiModelProperty(value = "买一价")
    private BigDecimal bp1;
    /**
     * 买二价
     */
    @ApiModelProperty(value = "买二价")
    private BigDecimal bp2;
    /**
     * 买三价
     */
    @ApiModelProperty(value = "买三价")
    private BigDecimal bp3;
    /**
     * 买四价
     */
    @ApiModelProperty(value = "买四价")
    private BigDecimal bp4;
    /**
     * 买五价
     */
    @ApiModelProperty(value = "买五价")
    private BigDecimal bp5;
    /**
     * 买一量
     */
    @ApiModelProperty(value = "买一量")
    private int bv1;
    /**
     * 买二量
     */
    @ApiModelProperty(value = "买二量")
    private int bv2;
    /**
     * 买三量
     */
    @ApiModelProperty(value = "买三量")
    private int bv3;
    /**
     * 买四量
     */
    @ApiModelProperty(value = "买四量")
    private int bv4;
    /**
     * 买五量
     */
    @ApiModelProperty(value = "买五量")
    private int bv5;
    /**
     * 内盘成交量
     */
    @ApiModelProperty(value = "内盘成交量")
    private int bai;
    /**
     * 外盘成交量
     */
    @ApiModelProperty(value = "外盘成交量")
    private int bao;
    /**
     * 最新成交量
     */
    @ApiModelProperty(value = "最新成交量")
    private int lba;
    /**
     * 时间戳
     */
    @ApiModelProperty(value = "时间戳")
    private long dt;

    /**
     * 涨跌值
     */
    @ApiModelProperty(value = "涨跌值")
    private BigDecimal rp;
    /**
     * 涨跌幅
     */
    @ApiModelProperty(value = "涨跌幅")
    private BigDecimal rf;


    /*
    0 futu_exch_type|
    1 contract_code|
    2 commodity_type|
    3 futu_product_type|
    4 second_code|
    5 sender_id|
    6 company_id|
    7 open_price|
    8 high_price|
    9 low_price|
    10 last_price|
    11 prev_price|
    12 up_price|
    13 down_price|
    14 business_balance|
    15 business_amount|
    16 pre_settle_price|
    17 position|
    18 settle_price|
    19 average_price|
    20 ask_price1|
    21 ask_price2|
    22 ask_price3|
    23 ask_price4|
    24 ask_price5|
    25 ask_volume1|
    26 ask_volume2|
    27 ask_volume3|
    28 ask_volume4|
    29 ask_volume5|
    30 bid_price1|
    31 bid_price2|
    32 bid_price3|
    33 bid_price4|
    34 bid_price5|
    35 bid_volume1|
    36 bid_volume2|
    37 bid_volume3|
    38 bid_volume4|
    39 bid_volume5|
    40 business_amount_in|
    41 business_amount_out|
    41 last_business_amount|
    43 date_time|

    SGX|1801|CN|1||||14655.000|14810.000|14652.500|14775.000|14652.500|16115.000|13185.000|3389576812.500|230181|14650.000|555874|0.000|
    14725.702|14775.000|14777.500|14780.000|14782.500|14785.000|25|182|198|209|180|14772.500|14770.000|14767.500|14765.000|14762.500|128|
    188|184|168|146|0|0|1|2018-01-26 11:08:25.957|
     */
    public static RealTimeData buildData(Map<String, String> datas, String topic) throws ParseException {
        RealTimeData data = new RealTimeData();
        data.setFet(datas.get("futu_exch_type"));
        data.setCc(datas.get("contract_code"));
        data.setCt(datas.get("commodity_type"));
        data.setFpt(datas.get("futu_product_type"));
        data.setSc(datas.get("second_code"));
        data.setSi(datas.get("sender_id"));
        data.setCi(datas.get("company_id"));
        data.setOp(StrUtil.isBlank(datas.get("open_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("open_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setHp(StrUtil.isBlank(datas.get("high_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("high_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setLp(StrUtil.isBlank(datas.get("low_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("low_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setNp(StrUtil.isBlank(datas.get("last_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("last_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setPp(StrUtil.isBlank(datas.get("prev_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("prev_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setUp(StrUtil.isBlank(datas.get("up_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("up_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setDp(StrUtil.isBlank(datas.get("down_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("down_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBb(StrUtil.isBlank(datas.get("business_balance")) ? BigDecimal.ZERO : new BigDecimal(datas.get("business_balance")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBa(StrUtil.isBlank(datas.get("business_amount")) ? 0 : Integer.parseInt(datas.get("business_amount")));
        data.setPsp(StrUtil.isBlank(datas.get("pre_settle_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("pre_settle_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setPo(StrUtil.isBlank(datas.get("position")) ? 0 : Integer.parseInt(datas.get("position")));
        data.setSp(StrUtil.isBlank(datas.get("settle_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("settle_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAvp(StrUtil.isBlank(datas.get("average_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("average_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp1(StrUtil.isBlank(datas.get("ask_price1")) ? BigDecimal.ZERO : new BigDecimal(datas.get("ask_price1")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp2(StrUtil.isBlank(datas.get("ask_price2")) ? BigDecimal.ZERO : new BigDecimal(datas.get("ask_price2")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp3(StrUtil.isBlank(datas.get("ask_price3")) ? BigDecimal.ZERO : new BigDecimal(datas.get("ask_price3")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp4(StrUtil.isBlank(datas.get("ask_price4")) ? BigDecimal.ZERO : new BigDecimal(datas.get("ask_price4")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp5(StrUtil.isBlank(datas.get("ask_price5")) ? BigDecimal.ZERO : new BigDecimal(datas.get("ask_price5")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAv1(StrUtil.isBlank(datas.get("ask_volume1")) ? 0 : Integer.parseInt(datas.get("ask_volume1")));
        data.setAv2(StrUtil.isBlank(datas.get("ask_volume2")) ? 0 : Integer.parseInt(datas.get("ask_volume2")));
        data.setAv3(StrUtil.isBlank(datas.get("ask_volume3")) ? 0 : Integer.parseInt(datas.get("ask_volume3")));
        data.setAv4(StrUtil.isBlank(datas.get("ask_volume4")) ? 0 : Integer.parseInt(datas.get("ask_volume4")));
        data.setAv5(StrUtil.isBlank(datas.get("ask_volume5")) ? 0 : Integer.parseInt(datas.get("ask_volume5")));
        data.setBp1(StrUtil.isBlank(datas.get("bid_price1")) ? BigDecimal.ZERO : new BigDecimal(datas.get("bid_price1")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp2(StrUtil.isBlank(datas.get("bid_price2")) ? BigDecimal.ZERO : new BigDecimal(datas.get("bid_price2")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp3(StrUtil.isBlank(datas.get("bid_price3")) ? BigDecimal.ZERO : new BigDecimal(datas.get("bid_price3")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp4(StrUtil.isBlank(datas.get("bid_price4")) ? BigDecimal.ZERO : new BigDecimal(datas.get("bid_price4")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp5(StrUtil.isBlank(datas.get("bid_price5")) ? BigDecimal.ZERO : new BigDecimal(datas.get("bid_price5")).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBv1(StrUtil.isBlank(datas.get("bid_volume1")) ? 0 : Integer.parseInt(datas.get("bid_volume1")));
        data.setBv2(StrUtil.isBlank(datas.get("bid_volume2")) ? 0 : Integer.parseInt(datas.get("bid_volume2")));
        data.setBv3(StrUtil.isBlank(datas.get("bid_volume3")) ? 0 : Integer.parseInt(datas.get("bid_volume3")));
        data.setBv4(StrUtil.isBlank(datas.get("bid_volume4")) ? 0 : Integer.parseInt(datas.get("bid_volume4")));
        data.setBv5(StrUtil.isBlank(datas.get("bid_volume5")) ? 0 : Integer.parseInt(datas.get("bid_volume5")));
        data.setBai(StrUtil.isBlank(datas.get("business_amount_in")) ? 0 : Integer.parseInt(datas.get("business_amount_in")));
        data.setBao(StrUtil.isBlank(datas.get("business_amount_out")) ? 0 : Integer.parseInt(datas.get("business_amount_out")));
        data.setLba(StrUtil.isBlank(datas.get("last_business_amount")) ? 0 : Integer.parseInt(datas.get("last_business_amount")));
        data.setDt(StrUtil.isBlank(datas.get("date_time")) ? 0L : new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(datas.get("date_time")).getTime());

        if ("futu.quotation_push".equals(topic)) {
            // 国内期货
            data.setRp(StrUtil.isBlank(datas.get("rise_price")) ? BigDecimal.ZERO : new BigDecimal(datas.get("rise_price")).setScale(4, BigDecimal.ROUND_HALF_UP));
            data.setRf(StrUtil.isBlank(datas.get("rise_pre")) ? BigDecimal.ZERO : new BigDecimal(datas.get("rise_pre")).setScale(4, BigDecimal.ROUND_HALF_UP));
            data.setCt(getCodeFromStr(datas.get("contract_code")));
            data.setCc(getContractFromStr(datas.get("contract_code"), data.getCt()));
            data.setDt(System.currentTimeMillis());
        } else {
            // 国际期货
            if (data.getPp().compareTo(BigDecimal.ZERO)==1){
                data.setRp(data.getNp().subtract(data.getPp()));
                data.setRf(data.getNp().subtract(data.getPp()).multiply(new BigDecimal(100)).divide(data.getPp(), 2, BigDecimal.ROUND_HALF_UP));
            }
        }
        return data;
    }

    private static String getCodeFromStr(String str) {
        if (StrUtil.isBlank(str)) return "";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if ((c <= 'z' && c >= 'a') || (c <= 'Z' && c >= 'A')) {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    private static String getContractFromStr(String str, String code) {
        return str.replace(code, "");
    }

    public static RealTimeData buildData(String[] args) throws ParseException {
        RealTimeData data = new RealTimeData();
        data.setFet(args[0]);
        data.setCc(args[1]);
        data.setCt(args[2]);
        data.setFpt(args[3]);
        data.setSc(args[4]);
        data.setSi(args[5]);
        data.setCi(args[6]);
        data.setOp(new BigDecimal(args[7]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setHp(new BigDecimal(args[8]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setLp(new BigDecimal(args[9]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setNp(new BigDecimal(args[10]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setPp(new BigDecimal(args[11]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setUp(new BigDecimal(args[12]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setDp(new BigDecimal(args[13]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBb(new BigDecimal(args[14]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBa(Integer.parseInt(args[15]));
        data.setPsp(new BigDecimal(args[16]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setPo(Integer.parseInt(args[17]));
        data.setSp(new BigDecimal(args[18]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAvp(new BigDecimal(args[19]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp1(new BigDecimal(args[20]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp2(new BigDecimal(args[21]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp3(new BigDecimal(args[22]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp4(new BigDecimal(args[23]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAp5(new BigDecimal(args[24]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setAv1(Integer.parseInt(args[25]));
        data.setAv2(Integer.parseInt(args[26]));
        data.setAv3(Integer.parseInt(args[27]));
        data.setAv4(Integer.parseInt(args[28]));
        data.setAv5(Integer.parseInt(args[29]));
        data.setBp1(new BigDecimal(args[30]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp2(new BigDecimal(args[31]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp3(new BigDecimal(args[32]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp4(new BigDecimal(args[33]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBp5(new BigDecimal(args[34]).setScale(4, BigDecimal.ROUND_HALF_UP));
        data.setBv1(Integer.parseInt(args[35]));
        data.setBv2(Integer.parseInt(args[36]));
        data.setBv3(Integer.parseInt(args[37]));
        data.setBv4(Integer.parseInt(args[38]));
        data.setBv5(Integer.parseInt(args[39]));
        data.setBai(Integer.parseInt(args[40]));
        data.setBao(Integer.parseInt(args[41]));
        data.setLba(Integer.parseInt(args[42]));
        data.setDt(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").parse(args[43]).getTime());
        return data;
    }

}
